import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Not, In, Like } from 'typeorm';
import { Injectable } from '@nestjs/common';
import { ResultData } from 'src/common/utils/result';
import { CreateRecordDto, UpdateRecordDto, QueryRecordDto } from './dto/record.dto';
import { RecordEntity } from './entities/record.entity';
import { isEmpty } from 'src/common/utils';

@Injectable()
export class RecordService {
  constructor(
    @InjectRepository(RecordEntity)
    private readonly recordEntityRep: Repository<RecordEntity>,
  ) {}

  async create(createRecordDto: CreateRecordDto) {
    const res = await this.recordEntityRep.save(createRecordDto);
    return ResultData.ok(res);
  }

  async findAll(query: QueryRecordDto) {
    const entity = this.recordEntityRep.createQueryBuilder('entity');
    entity.where({ delFlag: '0' });
    if (!isEmpty(query.id)) {
      entity.andWhere('entity.id = :id', { id: query.id });
    }
    if (!isEmpty(query.orderId)) {
      entity.andWhere('entity.orderId = :orderId', { orderId: query.orderId });
    }
    if (!isEmpty(query.orderNo)) {
      entity.andWhere('entity.orderNo = :orderNo', { orderNo: query.orderNo });
    }
    if (!isEmpty(query.outTradeNo)) {
      entity.andWhere('entity.outTradeNo = :outTradeNo', { outTradeNo: query.outTradeNo });
    }
    if (!isEmpty(query.transactionId)) {
      entity.andWhere('entity.transactionId = :transactionId', { transactionId: query.transactionId });
    }
    if (!isEmpty(query.outRefundNo)) {
      entity.andWhere('entity.outRefundNo = :outRefundNo', { outRefundNo: query.outRefundNo });
    }
    if (!isEmpty(query.refundId)) {
      entity.andWhere('entity.refundId = :refundId', { refundId: query.refundId });
    }
    if (!isEmpty(query.refundFee)) {
      entity.andWhere('entity.refundFee = :refundFee', { refundFee: query.refundFee });
    }
    if (!isEmpty(query.totalFee)) {
      entity.andWhere('entity.totalFee = :totalFee', { totalFee: query.totalFee });
    }
    if (!isEmpty(query.refundStatus)) {
      entity.andWhere('entity.refundStatus = :refundStatus', { refundStatus: query.refundStatus });
    }
    if (!isEmpty(query.refundDesc)) {
      entity.andWhere('entity.refundDesc = :refundDesc', { refundDesc: query.refundDesc });
    }
    if (!isEmpty(query.refundSuccessTime)) {
      entity.andWhere('entity.refundSuccessTime BETWEEN :start AND :end', { start: query.refundSuccessTime[0], end: query.refundSuccessTime[1] });
    }
    if (!isEmpty(query.createTime)) {
      entity.andWhere('entity.createTime BETWEEN :start AND :end', { start: query.createTime[0], end: query.createTime[1] });
    }
    if (!isEmpty(query.updateTime)) {
      entity.andWhere('entity.updateTime BETWEEN :start AND :end', { start: query.updateTime[0], end: query.updateTime[1] });
    }
    entity.select([
      'entity.id',
      'entity.orderId',
      'entity.orderNo',
      'entity.outTradeNo',
      'entity.transactionId',
      'entity.outRefundNo',
      'entity.refundId',
      'entity.refundFee',
      'entity.totalFee',
      'entity.refundStatus',
      'entity.refundDesc',
      'entity.refundSuccessTime',
    ]);

    if (query.orderByColumn && query.isAsc) {
      const key = query.isAsc === 'ascending' ? 'ASC' : 'DESC';
      entity.orderBy(`entity.${query.orderByColumn}`, key);
    }

    if (query.pageNum && query.pageSize) {
      entity.skip(query.pageSize * (query.pageNum - 1)).take(query.pageSize);
    }

    const [list, total] = await entity.getManyAndCount();

    return ResultData.ok({
      list,
      total,
    });
  }

  async findOne(id: number) {
    const res = await this.recordEntityRep.findOne({
      where: {
        id: id,
      },
    });
    return ResultData.ok(res);
  }

  async update(updateRecordDto: UpdateRecordDto) {
    const res = await this.recordEntityRep.update({ id: updateRecordDto.id }, updateRecordDto);
    return ResultData.ok({ value: res.affected >= 1 });
  }

  async remove(ids: number[]) {
    const res = await this.recordEntityRep.update({ id: In(ids) }, {});
    return ResultData.ok({ value: res.affected >= 1 });
  }
}
